class SettingOverride < ActiveRecord::Base
  belongs_to :setting
  has_many :axis_value_usages, :dependent => :destroy
  has_many :axis_values, :through => :axis_value_usages

  after_update :save_axis_value_usages
  validates_presence_of :value
  
  def new_axis_value_usages=(attributes)
    attributes.each do |attrs|
      axis_value_usages.build(attrs) unless attrs[:axis_value_id].empty?
    end
  end

  def existing_axis_value_usages=(attributes)
    axis_value_usages.reject(&:new_record?).each do |avu|
      attrs = attributes[avu.id.to_s]
      if attrs
        avu.attributes = attrs
      else
        AxisValueUsage.delete(avu)
      end
    end
  end

  def save_axis_value_usages
    axis_value_usages.each do |avu|
      avu.save
    end
  end

  def name
    setting.name
  end

  def context
    Axis.prioritized.collect { |a| (axis_value_for(a) || "*")}.join(".")
  end

  def axis_value_for(axis)
    axis_values.each do |av|
      return av.name if av.axis == axis
    end
    return nil
  end

  def priority
    result = 0
    axis_values.each do |av|
      result += av.axis.priority
    end
    return result
  end

  def has_axis?(axis)
    axis_values.each do |av|
      return true if av.axis == axis
    end
    return false
  end

  def axis_value_usage_for(axis)
    axis_value_usages.each do |avu|
      return avu if avu.axis_value.axis == axis
    end
    return nil
  end

  def satisfies(axes)
    return false if axes.size == 0
    return false if axis_values.size > axes.size
    result = true
    axis_values.each do |av|
      result &&= axes.include?(av.name)
    end
    return result
  end

  protected

  def validate
    return unless setting # accomodating tests here, probably shouldnt O_o
    setting.setting_overrides.each do |so|
      next if so == self
      next unless so.axis_value_usages.size == axis_value_usages.size
      collision = true
      axis_value_usages.collect { |avu| avu.axis_value }.each do |av|
        collision &&= so.axis_values.include?(av)
      end
      errors.add_to_base("You have a collision of axis values, that context is already occupied for this setting") if collision
    end
  end


end
